Motivation

Reviewer Comments addressed here:

Toward this end, the EOD waveform can be characterized by dozens of additional parameters beyond just the overall waveform duration. This is important in the present case because these parameters might provide clues about the underlying passive and ionic mechanisms that change EOD waveform at the level of the electrocyte, for example:

  1. the durations of P1 and P2 ✅,
  2. the rise slope of P1 ✅,
  3. the decay characteristics of P2 (single vs. multiple time constant) ✅
    nb: The single time constant seemed to fit adequately, not sure a multiple time constant is needed,
  4. changes in the delay between the peaks of P1 and P2 ✅,
  5. changes in the relative amplitude of P1 and P2, etc ✅.
  6. Parameters such as these should at least be reported for the sake of completeness ✅.
eod_measurement_path<-file.path(root, "output_data/norm_measurement_data.csv")
eod_measurement_data<-read.table(eod_measurement_path,header=T,sep = ",")
eod_measurement_data$duration<-eod_measurement_data$tT2-eod_measurement_data$tT1
eod_measurement_data$p1_duration<-eod_measurement_data$tZC2-eod_measurement_data$tP1
eod_measurement_data$p2_duration<-eod_measurement_data$tP2-eod_measurement_data$tZC2
eod_measurement_data$vP2.vP1.ratio<-eod_measurement_data$vP2/eod_measurement_data$vP1
# Convert treatdate to proper Date format

eod_measurement_data <- filter(eod_measurement_data, period=="EXPT")

eod_measurement_data <- eod_measurement_data %>%
  mutate(treatdate = as.Date(treatdate, format = "%d-%b"))

# Calculate n_days
eod_measurement_data <- eod_measurement_data %>%
  group_by(individual) %>%
  mutate(n_days = as.numeric(treatdate - min(treatdate))) %>%
  mutate(treat_day = case_when(
    (treatement %in% c("T8", "CON") & n_days == 8) ~ "last",
    (treatement %in% c("T8", "CON") & n_days == 0) ~ "first",
    (treatement == "T1" & n_days == 1) ~ "last",
    (treatement == "T1" & n_days == 0) ~ "first",
    TRUE ~ NA_character_ # All other rows are NA
  )) %>%
  ungroup()

# View the result
print(eod_measurement_data)
filt_eod_measurement_data <- eod_measurement_data %>%
  filter(!is.na(treat_day))
filt_eod_measurement_data$treat_day<-as.factor(filt_eod_measurement_data$treat_day)

Duration

Let’s check overall duration first. This has been updated to calculate duration the way that Mau does, so the results should be identical.

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "duration",
  y_axis_label = "EOD duration (msec)"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc

P1 Duration and P2 Duration

P1 duration does increase in T8 day, but not by a huge margin. P2 duration, however increases pretty substantially. Interesting…

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "p1_duration",
  y_axis_label = "P1 duration (msec)"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "p2_duration",
  y_axis_label = "P2 duration (msec)"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc
NA

Ratio of vP2 to vP1

A larger negative value means that P2 is “bigger” than P1. We can see that VP2 is always larger on the first day, but becomes more proportional after 8 days of T treatment. Does this suggest less Na+ expression?

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "vP2.vP1.ratio",
  y_axis_label = "vP2/vP1 ratio"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "vP2",
  y_axis_label = "vP2"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "vP1",
  y_axis_label = "vP1"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc

P1-P2 Delay

Since P1 is defined as T=0, then tP2 is the relative timing of P2. We can see that it takes longer to reach P2 after 8 days of T treatment, suggesting the action potentials are delayed relative to each other (capacitance?)

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "tP2",
  y_axis_label = "P1-P2 Delay (msec)"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc

P2 Decay Time Constant

A larger τ indicates that the decay happens more rapidly. This means P2’s amplitude diminishes over a larger time after testasterone treatment. This suggests increased potassium channel expression, I think.

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "decay_tau",
  y_axis_label = "τ"
)

# Display the plot
print(results$plot)

results$anova
results$posthoc

Slope of P1

There is no significant difference here.

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "sS1",
  y_axis_label = "Slope of P1"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
NA

P0

P0 does in fact get larger with testasterone treatment as well, though interestingly, the peak voltage stays the same, suggesting that this change is because the peak is broader (lasts longer). Not sure what would affect this, other than the electrocyte getting thicker? We don’t know much about the ion channels present on the stalks, so this is an interesting point to consider in a future study.

results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "aP0",
  y_axis_label = "Area P0"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
results <- create_significance_plot(
  data = filt_eod_measurement_data,
  y_variable = "vP0",
  y_axis_label = "Voltage of P0"
)
No significant differences found between groups.
# Display the plot
print(results$plot)

results$anova
results$posthoc
NA

Summary Table of All Comparisions

This code generates a summary table and outputs to word for editing and inclusion in the manuscript.

statistics <- c("duration", "p1_duration", "p2_duration", "vP2.vP1.ratio", "tP2", "decay_tau","aP0","vP0","sS1","vP1","vP2")

# Filter, summarize, and format
summary_table <- filt_eod_measurement_data %>%
  group_by(treat_day, treatement) %>%            # Group by n_days and treatment
  summarise(across(all_of(statistics),
                   ~ sprintf("%.2f ± %.2f", 
                             mean(.x, na.rm = TRUE), 
                             sd(.x, na.rm = TRUE)),
                   .names = "{col}")) %>%     # Combine mean and sd into a single column
  ungroup()                                   # Remove grouping
`summarise()` has grouped output by 'treat_day'. You can override using the `.groups` argument.
colnames(summary_table)<-c("Treatment Day","Treatment","Duration","P1 Duration","P2 Duration","vP2/vP1","tP2","τ","aP0","vP0","sS1","vP1","vP2")

# Create the flextable
flextable_table <- flextable(summary_table) %>%
  bg(part = "header", bg = "#D3D3D3") %>%  # Set header background color
  bold(part = "header") %>%               # Bold the header row
  fontsize(size = 10, part = "all") %>%   # Set font size for the entire table
  autofit() %>%                           # Adjust column widths
  set_table_properties(layout = "autofit") %>%      # Fit table to layout
  line_spacing(i = NULL, space = 1.2)     # Add line spacing for better readability

# Define landscape section properties
landscape_section <- block_section(
  prop_section(
    page_size = page_size(orient = "landscape") # Set the page orientation to landscape
  )
)

# Create the Word document
doc <- read_docx() %>%
  body_add_flextable(flextable_table) %>% # Add the flextable
  body_add(landscape_section)      # Apply landscape section properties


# Export the Word document
print(doc, target = file.path(root,"output_data/eod_summary_norm.docx"))

flextable_table

Treatment Day

Treatment

Duration

P1 Duration

P2 Duration

vP2/vP1

tP2

τ

aP0

vP0

sS1

vP1

vP2

first

CON

0.68 ± 0.13

0.03 ± 0.00

0.04 ± 0.00

-1.44 ± 0.20

0.07 ± 0.01

31.06 ± 4.70

-2.77 ± 0.83

-0.02 ± 0.01

291.38 ± 71.18

0.41 ± 0.03

-0.59 ± 0.03

first

T1

0.78 ± 0.07

0.04 ± 0.00

0.04 ± 0.01

-1.46 ± 0.20

0.08 ± 0.01

26.88 ± 5.54

-3.22 ± 1.31

-0.03 ± 0.01

242.45 ± 47.25

0.41 ± 0.03

-0.59 ± 0.03

first

T8

0.69 ± 0.09

0.03 ± 0.00

0.04 ± 0.00

-1.54 ± 0.21

0.07 ± 0.01

32.04 ± 4.08

-2.37 ± 0.50

-0.02 ± 0.00

278.16 ± 64.73

0.40 ± 0.03

-0.60 ± 0.03

last

CON

0.68 ± 0.14

0.04 ± 0.01

0.04 ± 0.00

-1.44 ± 0.21

0.07 ± 0.01

30.24 ± 5.40

-2.65 ± 0.79

-0.02 ± 0.01

293.72 ± 77.33

0.41 ± 0.03

-0.59 ± 0.03

last

T1

0.83 ± 0.09

0.04 ± 0.01

0.04 ± 0.01

-1.46 ± 0.18

0.08 ± 0.01

25.82 ± 5.12

-3.25 ± 1.31

-0.03 ± 0.01

237.71 ± 45.81

0.41 ± 0.03

-0.59 ± 0.03

last

T8

1.35 ± 0.20

0.07 ± 0.01

0.09 ± 0.03

-1.08 ± 0.28

0.16 ± 0.04

11.18 ± 3.07

-3.98 ± 1.08

-0.02 ± 0.01

227.10 ± 57.83

0.49 ± 0.08

-0.51 ± 0.08

library(multcompView)
library(tidyr)
library(dplyr)

# Define the list of variables for which you want to add significance letters.
statistics <- c("duration", "p1_duration", "p2_duration", "vP2.vP1.ratio", 
                "tP2", "decay_tau", "aP0", "vP0", "sS1", "vP1", "vP2")

get_letters_by_day <- function(df, group_info, var) {
  # Run Tukey's test for the given variable
  tukey_res <- tukey_hsd(df, as.formula(paste(var, "~ treatement")))
  
  # Create a matrix of p-values between treatment groups
  groups <- sort(unique(df$treatement))
  pmat <- matrix(1, nrow = length(groups), ncol = length(groups),
                 dimnames = list(groups, groups))
  
  if(nrow(tukey_res) > 0) {
    for(i in seq_len(nrow(tukey_res))) {
      grp1 <- tukey_res$group1[i]
      grp2 <- tukey_res$group2[i]
      p_val <- tukey_res$p.adj[i]
      pmat[grp1, grp2] <- p_val
      pmat[grp2, grp1] <- p_val
    }
  }
  
  # Compute grouping letters
  letters_out <- multcompLetters(pmat, threshold = 0.05)$Letters
  
  # Return only the treatment and letter columns.
  # The grouping variable (treat_day) is added automatically.
  data.frame(treatement = names(letters_out), 
             letter = letters_out, 
             stringsAsFactors = FALSE)
}



letters_list <- lapply(statistics, function(var) {
  filt_eod_measurement_data %>%
    group_by(treat_day) %>%
    group_modify(~ get_letters_by_day(.x, .y, var)) %>%
    ungroup() %>%
    mutate(variable = var)
})
all_letters <- bind_rows(letters_list)



# Now, create your summary table as before.
# (We assume the summary_table was computed as in your previous chunk.)
summary_table <- filt_eod_measurement_data %>%
  group_by(treat_day, treatement) %>%  # Group by day and treatment
  summarise(across(all_of(statistics),
                   ~ sprintf("%.2f ± %.2f", 
                             mean(.x, na.rm = TRUE), 
                             sd(.x, na.rm = TRUE))),
            .groups = "drop")  # Combine mean and sd into a single column

# For nicer column names, rename (you can adjust this mapping as needed).
colnames(summary_table) <- c("Treatment Day","Treatment",
                             "Duration","P1 Duration","P2 Duration",
                             "vP2/vP1","tP2","τ","aP0","vP0","sS1","vP1","vP2")

# Since our letters are keyed by the original variable names (e.g., "duration") 
# we set up a mapping to match the summary_table columns.
mapping_df <- tibble(
  Variable = c("Duration", "P1 Duration", "P2 Duration", "vP2/vP1", 
               "tP2", "τ", "aP0", "vP0", "sS1", "vP1", "vP2"),
  var = statistics
)

# Reshape the summary_table to long format to merge the letters.
summary_long <- summary_table %>%
  pivot_longer(cols = -c(`Treatment Day`, Treatment),
               names_to = "Variable",
               values_to = "Summary") %>%
  left_join(mapping_df, by = "Variable")

# Merge with the letters (join by treat_day/Treatment and the variable key).
# Note: In summary_table, "Treatment Day" corresponds to "treat_day" in all_letters.
summary_long <- summary_long %>%
  left_join(all_letters, by = c("var" = "variable",
                                "Treatment Day" = "treat_day",
                                "Treatment" = "treatement"))

# Append the significance letter (if available) to the summary string.
summary_long <- summary_long %>%
  mutate(Summary = ifelse(is.na(letter),
                          Summary,
                          paste0(Summary, " (", letter, ")")))

# (Optional) Pivot back to wide format.
summary_wide <- summary_long %>%
  select(-var, -letter) %>%
  pivot_wider(names_from = Variable, values_from = Summary)

# Create a flextable from the updated summary_wide table.
flextable_table_sig <- flextable(summary_wide) %>%
  bg(part = "header", bg = "#D3D3D3") %>%  # Header background color
  bold(part = "header") %>%               # Bold header row
  fontsize(size = 10, part = "all") %>%   # Font size for entire table
  autofit() %>%                           # Adjust column widths
  set_table_properties(layout = "autofit") %>%      # Fit table to layout
  line_spacing(i = NULL, space = 1.2)       # Better readability

# Define landscape section properties for Word export
landscape_section <- block_section(
  prop_section(
    page_size = page_size(orient = "landscape") # Landscape orientation
  )
)

# Create the Word document with the updated flextable.
doc <- read_docx() %>%
  body_add_flextable(flextable_table_sig) %>%  # Add flextable
  body_add(landscape_section)                  # Apply landscape layout

# Export the Word document.
print(doc, target = file.path(root,"output_data/eod_summary_norm_with_sig.docx"))

# Display the updated flextable in the R Markdown output.
flextable_table_sig

Treatment Day

Treatment

Duration

P1 Duration

P2 Duration

vP2/vP1

tP2

τ

aP0

vP0

sS1

vP1

vP2

first

CON

0.68 ± 0.13 (a)

0.03 ± 0.00 (ab)

0.04 ± 0.00 (a)

-1.44 ± 0.20 (a)

0.07 ± 0.01 (ab)

31.06 ± 4.70 (a)

-2.77 ± 0.83 (a)

-0.02 ± 0.01 (a)

291.38 ± 71.18 (a)

0.41 ± 0.03 (a)

-0.59 ± 0.03 (a)

first

T1

0.78 ± 0.07 (a)

0.04 ± 0.00 (a)

0.04 ± 0.01 (a)

-1.46 ± 0.20 (a)

0.08 ± 0.01 (a)

26.88 ± 5.54 (a)

-3.22 ± 1.31 (a)

-0.03 ± 0.01 (a)

242.45 ± 47.25 (a)

0.41 ± 0.03 (a)

-0.59 ± 0.03 (a)

first

T8

0.69 ± 0.09 (a)

0.03 ± 0.00 (b)

0.04 ± 0.00 (a)

-1.54 ± 0.21 (a)

0.07 ± 0.01 (b)

32.04 ± 4.08 (a)

-2.37 ± 0.50 (a)

-0.02 ± 0.00 (a)

278.16 ± 64.73 (a)

0.40 ± 0.03 (a)

-0.60 ± 0.03 (a)

last

CON

0.68 ± 0.14 (a)

0.04 ± 0.01 (a)

0.04 ± 0.00 (a)

-1.44 ± 0.21 (a)

0.07 ± 0.01 (a)

30.24 ± 5.40 (a)

-2.65 ± 0.79 (a)

-0.02 ± 0.01 (a)

293.72 ± 77.33 (a)

0.41 ± 0.03 (a)

-0.59 ± 0.03 (a)

last

T1

0.83 ± 0.09 (a)

0.04 ± 0.01 (a)

0.04 ± 0.01 (a)

-1.46 ± 0.18 (a)

0.08 ± 0.01 (a)

25.82 ± 5.12 (a)

-3.25 ± 1.31 (a)

-0.03 ± 0.01 (a)

237.71 ± 45.81 (a)

0.41 ± 0.03 (a)

-0.59 ± 0.03 (a)

last

T8

1.35 ± 0.20 (b)

0.07 ± 0.01 (b)

0.09 ± 0.03 (b)

-1.08 ± 0.28 (b)

0.16 ± 0.04 (b)

11.18 ± 3.07 (b)

-3.98 ± 1.08 (a)

-0.02 ± 0.01 (a)

227.10 ± 57.83 (a)

0.49 ± 0.08 (b)

-0.51 ± 0.08 (b)

LS0tCnRpdGxlOiAiRGVlcCBEaXZlIG9uIEVPRCBDaGFuZ2VzIHdpdGggVGVzdGFzdGVyb25lIFRyZWF0bWVudCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgTW90aXZhdGlvbgoKUmV2aWV3ZXIgQ29tbWVudHMgYWRkcmVzc2VkIGhlcmU6CgpUb3dhcmQgdGhpcyBlbmQsIHRoZSBFT0Qgd2F2ZWZvcm0gY2FuIGJlIGNoYXJhY3Rlcml6ZWQgYnkgZG96ZW5zIG9mIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBiZXlvbmQganVzdCB0aGUgb3ZlcmFsbCB3YXZlZm9ybSBkdXJhdGlvbi4gVGhpcyBpcyBpbXBvcnRhbnQgaW4gdGhlIHByZXNlbnQgY2FzZSBiZWNhdXNlIHRoZXNlIHBhcmFtZXRlcnMgbWlnaHQgcHJvdmlkZSBjbHVlcyBhYm91dCB0aGUgdW5kZXJseWluZyBwYXNzaXZlIGFuZCBpb25pYyBtZWNoYW5pc21zIHRoYXQgY2hhbmdlIEVPRCB3YXZlZm9ybSBhdCB0aGUgbGV2ZWwgb2YgdGhlIGVsZWN0cm9jeXRlLCBmb3IgZXhhbXBsZToKCjEuIHRoZSBkdXJhdGlvbnMgb2YgUDEgYW5kIFAyIOKchSwgCjIuIHRoZSByaXNlIHNsb3BlIG9mIFAxIOKchSwgCjMuIHRoZSBkZWNheSBjaGFyYWN0ZXJpc3RpY3Mgb2YgUDIgKHNpbmdsZSB2cy4gbXVsdGlwbGUgdGltZSBjb25zdGFudCkg4pyFICAKICAgIG5iOiBUaGUgc2luZ2xlIHRpbWUgY29uc3RhbnQgc2VlbWVkIHRvIGZpdCBhZGVxdWF0ZWx5LCBub3Qgc3VyZSBhIG11bHRpcGxlIHRpbWUgY29uc3RhbnQgaXMgbmVlZGVkLCAKNC4gY2hhbmdlcyBpbiB0aGUgZGVsYXkgYmV0d2VlbiB0aGUgcGVha3Mgb2YgUDEgYW5kIFAyIOKchSwgCjUuIGNoYW5nZXMgaW4gdGhlIHJlbGF0aXZlIGFtcGxpdHVkZSBvZiBQMSBhbmQgUDIsIGV0YyDinIUuIAo2LiBQYXJhbWV0ZXJzIHN1Y2ggYXMgdGhlc2Ugc2hvdWxkIGF0IGxlYXN0IGJlIHJlcG9ydGVkIGZvciB0aGUgc2FrZSBvZiBjb21wbGV0ZW5lc3Mg4pyFLgoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpyb290PC1ycHJvanJvb3Q6OmZpbmRfcm9vdCgiLmdpdC9pbmRleCIpCmtuaXRyOjpvcHRzX2tuaXQkc2V0KHJvb3QuZGlyID0gcm9vdCkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShtdWx0Y29tcFZpZXcpCmxpYnJhcnkoZmxleHRhYmxlKQpsaWJyYXJ5KG9mZmljZXIpCnNvdXJjZSgic3RhdHNfYW5kX3Bsb3QuUiIpCmBgYAoKYGBge3J9CmVvZF9tZWFzdXJlbWVudF9wYXRoPC1maWxlLnBhdGgocm9vdCwgIm91dHB1dF9kYXRhL25vcm1fbWVhc3VyZW1lbnRfZGF0YS5jc3YiKQplb2RfbWVhc3VyZW1lbnRfZGF0YTwtcmVhZC50YWJsZShlb2RfbWVhc3VyZW1lbnRfcGF0aCxoZWFkZXI9VCxzZXAgPSAiLCIpCmBgYAoKYGBge3J9CmVvZF9tZWFzdXJlbWVudF9kYXRhJGR1cmF0aW9uPC1lb2RfbWVhc3VyZW1lbnRfZGF0YSR0VDItZW9kX21lYXN1cmVtZW50X2RhdGEkdFQxCmVvZF9tZWFzdXJlbWVudF9kYXRhJHAxX2R1cmF0aW9uPC1lb2RfbWVhc3VyZW1lbnRfZGF0YSR0WkMyLWVvZF9tZWFzdXJlbWVudF9kYXRhJHRQMQplb2RfbWVhc3VyZW1lbnRfZGF0YSRwMl9kdXJhdGlvbjwtZW9kX21lYXN1cmVtZW50X2RhdGEkdFAyLWVvZF9tZWFzdXJlbWVudF9kYXRhJHRaQzIKZW9kX21lYXN1cmVtZW50X2RhdGEkdlAyLnZQMS5yYXRpbzwtZW9kX21lYXN1cmVtZW50X2RhdGEkdlAyL2VvZF9tZWFzdXJlbWVudF9kYXRhJHZQMQpgYGAKCmBgYHtyfQojIENvbnZlcnQgdHJlYXRkYXRlIHRvIHByb3BlciBEYXRlIGZvcm1hdAoKZW9kX21lYXN1cmVtZW50X2RhdGEgPC0gZmlsdGVyKGVvZF9tZWFzdXJlbWVudF9kYXRhLCBwZXJpb2Q9PSJFWFBUIikKCmVvZF9tZWFzdXJlbWVudF9kYXRhIDwtIGVvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIG11dGF0ZSh0cmVhdGRhdGUgPSBhcy5EYXRlKHRyZWF0ZGF0ZSwgZm9ybWF0ID0gIiVkLSViIikpCgojIENhbGN1bGF0ZSBuX2RheXMKZW9kX21lYXN1cmVtZW50X2RhdGEgPC0gZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgZ3JvdXBfYnkoaW5kaXZpZHVhbCkgJT4lCiAgbXV0YXRlKG5fZGF5cyA9IGFzLm51bWVyaWModHJlYXRkYXRlIC0gbWluKHRyZWF0ZGF0ZSkpKSAlPiUKICBtdXRhdGUodHJlYXRfZGF5ID0gY2FzZV93aGVuKAogICAgKHRyZWF0ZW1lbnQgJWluJSBjKCJUOCIsICJDT04iKSAmIG5fZGF5cyA9PSA4KSB+ICJsYXN0IiwKICAgICh0cmVhdGVtZW50ICVpbiUgYygiVDgiLCAiQ09OIikgJiBuX2RheXMgPT0gMCkgfiAiZmlyc3QiLAogICAgKHRyZWF0ZW1lbnQgPT0gIlQxIiAmIG5fZGF5cyA9PSAxKSB+ICJsYXN0IiwKICAgICh0cmVhdGVtZW50ID09ICJUMSIgJiBuX2RheXMgPT0gMCkgfiAiZmlyc3QiLAogICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8gIyBBbGwgb3RoZXIgcm93cyBhcmUgTkEKICApKSAlPiUKICB1bmdyb3VwKCkKCiMgVmlldyB0aGUgcmVzdWx0CnByaW50KGVvZF9tZWFzdXJlbWVudF9kYXRhKQpgYGAKCmBgYHtyfQpmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhIDwtIGVvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIGZpbHRlcighaXMubmEodHJlYXRfZGF5KSkKZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSR0cmVhdF9kYXk8LWFzLmZhY3RvcihmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhJHRyZWF0X2RheSkKYGBgCgoKCiMjIER1cmF0aW9uCkxldCdzIGNoZWNrIG92ZXJhbGwgZHVyYXRpb24gZmlyc3QuICBUaGlzIGhhcyBiZWVuIHVwZGF0ZWQgdG8gY2FsY3VsYXRlIGR1cmF0aW9uIHRoZSB3YXkgdGhhdCBNYXUgZG9lcywgc28gdGhlIHJlc3VsdHMgc2hvdWxkIGJlIGlkZW50aWNhbC4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gImR1cmF0aW9uIiwKICB5X2F4aXNfbGFiZWwgPSAiRU9EIGR1cmF0aW9uIChtc2VjKSIKKQoKIyBEaXNwbGF5IHRoZSBwbG90CnByaW50KHJlc3VsdHMkcGxvdCkKcmVzdWx0cyRhbm92YQpyZXN1bHRzJHBvc3Rob2MKYGBgCiMjIFAxIER1cmF0aW9uIGFuZCBQMiBEdXJhdGlvbgpQMSBkdXJhdGlvbiBkb2VzIGluY3JlYXNlIGluIFQ4IGRheSwgYnV0IG5vdCBieSBhIGh1Z2UgbWFyZ2luLiAgUDIgZHVyYXRpb24sIGhvd2V2ZXIgaW5jcmVhc2VzIHByZXR0eSBzdWJzdGFudGlhbGx5LiAgSW50ZXJlc3RpbmcuLi4KYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAicDFfZHVyYXRpb24iLAogIHlfYXhpc19sYWJlbCA9ICJQMSBkdXJhdGlvbiAobXNlYykiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKCgpgYGB7cn0KCnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAicDJfZHVyYXRpb24iLAogIHlfYXhpc19sYWJlbCA9ICJQMiBkdXJhdGlvbiAobXNlYykiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCgpgYGAKCiMjIFJhdGlvIG9mIHZQMiB0byB2UDEKCkEgbGFyZ2VyIG5lZ2F0aXZlIHZhbHVlIG1lYW5zIHRoYXQgUDIgaXMgImJpZ2dlciIgdGhhbiBQMS4gIFdlIGNhbiBzZWUgdGhhdCBWUDIgaXMgYWx3YXlzIGxhcmdlciBvbiB0aGUgZmlyc3QgZGF5LCBidXQgYmVjb21lcyBtb3JlIHByb3BvcnRpb25hbCBhZnRlciA4IGRheXMgb2YgVCB0cmVhdG1lbnQuICBEb2VzIHRoaXMgc3VnZ2VzdCBsZXNzIE5hKyBleHByZXNzaW9uPwoKYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAidlAyLnZQMS5yYXRpbyIsCiAgeV9heGlzX2xhYmVsID0gInZQMi92UDEgcmF0aW8iCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKCgpgYGB7cn0KcmVzdWx0cyA8LSBjcmVhdGVfc2lnbmlmaWNhbmNlX3Bsb3QoCiAgZGF0YSA9IGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEsCiAgeV92YXJpYWJsZSA9ICJ2UDIiLAogIHlfYXhpc19sYWJlbCA9ICJ2UDIiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCmBgYAoKYGBge3J9CnJlc3VsdHMgPC0gY3JlYXRlX3NpZ25pZmljYW5jZV9wbG90KAogIGRhdGEgPSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhLAogIHlfdmFyaWFibGUgPSAidlAxIiwKICB5X2F4aXNfbGFiZWwgPSAidlAxIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKCgojIyBQMS1QMiBEZWxheQpTaW5jZSBQMSBpcyBkZWZpbmVkIGFzIFQ9MCwgdGhlbiB0UDIgaXMgdGhlIHJlbGF0aXZlIHRpbWluZyBvZiBQMi4KV2UgY2FuIHNlZSB0aGF0IGl0IHRha2VzIGxvbmdlciB0byByZWFjaCBQMiBhZnRlciA4IGRheXMgb2YgVCB0cmVhdG1lbnQsIHN1Z2dlc3RpbmcgdGhlIGFjdGlvbiBwb3RlbnRpYWxzIGFyZSBkZWxheWVkIHJlbGF0aXZlIHRvIGVhY2ggb3RoZXIgKGNhcGFjaXRhbmNlPykKCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInRQMiIsCiAgeV9heGlzX2xhYmVsID0gIlAxLVAyIERlbGF5IChtc2VjKSIKKQoKIyBEaXNwbGF5IHRoZSBwbG90CnByaW50KHJlc3VsdHMkcGxvdCkKcmVzdWx0cyRhbm92YQpyZXN1bHRzJHBvc3Rob2MKYGBgCiMjIFAyIERlY2F5IFRpbWUgQ29uc3RhbnQKIEEgbGFyZ2VyIM+EIGluZGljYXRlcyB0aGF0IHRoZSBkZWNheSBoYXBwZW5zIG1vcmUgcmFwaWRseS4gVGhpcyBtZWFucyBQMidzIGFtcGxpdHVkZSBkaW1pbmlzaGVzIG92ZXIgYSBsYXJnZXIgdGltZSBhZnRlciB0ZXN0YXN0ZXJvbmUgdHJlYXRtZW50LiAgVGhpcyBzdWdnZXN0cyBpbmNyZWFzZWQgcG90YXNzaXVtIGNoYW5uZWwgZXhwcmVzc2lvbiwgSSB0aGluay4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gImRlY2F5X3RhdSIsCiAgeV9heGlzX2xhYmVsID0gIs+EIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKIyMgU2xvcGUgb2YgUDEKClRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaGVyZS4KCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInNTMSIsCiAgeV9heGlzX2xhYmVsID0gIlNsb3BlIG9mIFAxIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwoKYGBgCiMjIFAwCgpQMCBkb2VzIGluIGZhY3QgZ2V0IGxhcmdlciB3aXRoIHRlc3Rhc3Rlcm9uZSB0cmVhdG1lbnQgYXMgd2VsbCwgdGhvdWdoIGludGVyZXN0aW5nbHksIHRoZSBwZWFrIHZvbHRhZ2Ugc3RheXMgdGhlIHNhbWUsIHN1Z2dlc3RpbmcgdGhhdCB0aGlzIGNoYW5nZSBpcyBiZWNhdXNlIHRoZSBwZWFrIGlzIGJyb2FkZXIgKGxhc3RzIGxvbmdlcikuICBOb3Qgc3VyZSB3aGF0IHdvdWxkIGFmZmVjdCB0aGlzLCBvdGhlciB0aGFuIHRoZSBlbGVjdHJvY3l0ZSBnZXR0aW5nIHRoaWNrZXI/ICBXZSBkb24ndCBrbm93IG11Y2ggYWJvdXQgdGhlIGlvbiBjaGFubmVscyBwcmVzZW50IG9uIHRoZSBzdGFsa3MsIHNvIHRoaXMgaXMgYW4gaW50ZXJlc3RpbmcgcG9pbnQgdG8gY29uc2lkZXIgaW4gYSBmdXR1cmUgc3R1ZHkuCgpgYGB7cn0KcmVzdWx0cyA8LSBjcmVhdGVfc2lnbmlmaWNhbmNlX3Bsb3QoCiAgZGF0YSA9IGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEsCiAgeV92YXJpYWJsZSA9ICJhUDAiLAogIHlfYXhpc19sYWJlbCA9ICJBcmVhIFAwIgopCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQocmVzdWx0cyRwbG90KQpyZXN1bHRzJGFub3ZhCnJlc3VsdHMkcG9zdGhvYwpgYGAKCmBgYHtyfQpyZXN1bHRzIDwtIGNyZWF0ZV9zaWduaWZpY2FuY2VfcGxvdCgKICBkYXRhID0gZmlsdF9lb2RfbWVhc3VyZW1lbnRfZGF0YSwKICB5X3ZhcmlhYmxlID0gInZQMCIsCiAgeV9heGlzX2xhYmVsID0gIlZvbHRhZ2Ugb2YgUDAiCikKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChyZXN1bHRzJHBsb3QpCnJlc3VsdHMkYW5vdmEKcmVzdWx0cyRwb3N0aG9jCgpgYGAKIyMgU3VtbWFyeSBUYWJsZSBvZiBBbGwgQ29tcGFyaXNpb25zCgpUaGlzIGNvZGUgZ2VuZXJhdGVzIGEgc3VtbWFyeSB0YWJsZSBhbmQgb3V0cHV0cyB0byB3b3JkIGZvciBlZGl0aW5nIGFuZCBpbmNsdXNpb24gaW4gdGhlIG1hbnVzY3JpcHQuCgpgYGB7cn0Kc3RhdGlzdGljcyA8LSBjKCJkdXJhdGlvbiIsICJwMV9kdXJhdGlvbiIsICJwMl9kdXJhdGlvbiIsICJ2UDIudlAxLnJhdGlvIiwgInRQMiIsICJkZWNheV90YXUiLCJhUDAiLCJ2UDAiLCJzUzEiLCJ2UDEiLCJ2UDIiKQoKIyBGaWx0ZXIsIHN1bW1hcml6ZSwgYW5kIGZvcm1hdApzdW1tYXJ5X3RhYmxlIDwtIGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgZ3JvdXBfYnkodHJlYXRfZGF5LCB0cmVhdGVtZW50KSAlPiUgICAgICAgICAgICAjIEdyb3VwIGJ5IG5fZGF5cyBhbmQgdHJlYXRtZW50CiAgc3VtbWFyaXNlKGFjcm9zcyhhbGxfb2Yoc3RhdGlzdGljcyksCiAgICAgICAgICAgICAgICAgICB+IHNwcmludGYoIiUuMmYgwrEgJS4yZiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oLngsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkKC54LCBuYS5ybSA9IFRSVUUpKSwKICAgICAgICAgICAgICAgICAgIC5uYW1lcyA9ICJ7Y29sfSIpKSAlPiUgICAgICMgQ29tYmluZSBtZWFuIGFuZCBzZCBpbnRvIGEgc2luZ2xlIGNvbHVtbgogIHVuZ3JvdXAoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZW1vdmUgZ3JvdXBpbmcKCgpjb2xuYW1lcyhzdW1tYXJ5X3RhYmxlKTwtYygiVHJlYXRtZW50IERheSIsIlRyZWF0bWVudCIsIkR1cmF0aW9uIiwiUDEgRHVyYXRpb24iLCJQMiBEdXJhdGlvbiIsInZQMi92UDEiLCJ0UDIiLCLPhCIsImFQMCIsInZQMCIsInNTMSIsInZQMSIsInZQMiIpCgojIENyZWF0ZSB0aGUgZmxleHRhYmxlCmZsZXh0YWJsZV90YWJsZSA8LSBmbGV4dGFibGUoc3VtbWFyeV90YWJsZSkgJT4lCiAgYmcocGFydCA9ICJoZWFkZXIiLCBiZyA9ICIjRDNEM0QzIikgJT4lICAjIFNldCBoZWFkZXIgYmFja2dyb3VuZCBjb2xvcgogIGJvbGQocGFydCA9ICJoZWFkZXIiKSAlPiUgICAgICAgICAgICAgICAjIEJvbGQgdGhlIGhlYWRlciByb3cKICBmb250c2l6ZShzaXplID0gMTAsIHBhcnQgPSAiYWxsIikgJT4lICAgIyBTZXQgZm9udCBzaXplIGZvciB0aGUgZW50aXJlIHRhYmxlCiAgYXV0b2ZpdCgpICU+JSAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQWRqdXN0IGNvbHVtbiB3aWR0aHMKICBzZXRfdGFibGVfcHJvcGVydGllcyhsYXlvdXQgPSAiYXV0b2ZpdCIpICU+JSAgICAgICMgRml0IHRhYmxlIHRvIGxheW91dAogIGxpbmVfc3BhY2luZyhpID0gTlVMTCwgc3BhY2UgPSAxLjIpICAgICAjIEFkZCBsaW5lIHNwYWNpbmcgZm9yIGJldHRlciByZWFkYWJpbGl0eQoKIyBEZWZpbmUgbGFuZHNjYXBlIHNlY3Rpb24gcHJvcGVydGllcwpsYW5kc2NhcGVfc2VjdGlvbiA8LSBibG9ja19zZWN0aW9uKAogIHByb3Bfc2VjdGlvbigKICAgIHBhZ2Vfc2l6ZSA9IHBhZ2Vfc2l6ZShvcmllbnQgPSAibGFuZHNjYXBlIikgIyBTZXQgdGhlIHBhZ2Ugb3JpZW50YXRpb24gdG8gbGFuZHNjYXBlCiAgKQopCgojIENyZWF0ZSB0aGUgV29yZCBkb2N1bWVudApkb2MgPC0gcmVhZF9kb2N4KCkgJT4lCiAgYm9keV9hZGRfZmxleHRhYmxlKGZsZXh0YWJsZV90YWJsZSkgJT4lICMgQWRkIHRoZSBmbGV4dGFibGUKICBib2R5X2FkZChsYW5kc2NhcGVfc2VjdGlvbikgICAgICAjIEFwcGx5IGxhbmRzY2FwZSBzZWN0aW9uIHByb3BlcnRpZXMKCgojIEV4cG9ydCB0aGUgV29yZCBkb2N1bWVudApwcmludChkb2MsIHRhcmdldCA9IGZpbGUucGF0aChyb290LCJvdXRwdXRfZGF0YS9lb2Rfc3VtbWFyeV9ub3JtLmRvY3giKSkKCmZsZXh0YWJsZV90YWJsZQpgYGAKCgpgYGB7cn0KbGlicmFyeShtdWx0Y29tcFZpZXcpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCgojIERlZmluZSB0aGUgbGlzdCBvZiB2YXJpYWJsZXMgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGFkZCBzaWduaWZpY2FuY2UgbGV0dGVycy4Kc3RhdGlzdGljcyA8LSBjKCJkdXJhdGlvbiIsICJwMV9kdXJhdGlvbiIsICJwMl9kdXJhdGlvbiIsICJ2UDIudlAxLnJhdGlvIiwgCiAgICAgICAgICAgICAgICAidFAyIiwgImRlY2F5X3RhdSIsICJhUDAiLCAidlAwIiwgInNTMSIsICJ2UDEiLCAidlAyIikKCmdldF9sZXR0ZXJzX2J5X2RheSA8LSBmdW5jdGlvbihkZiwgZ3JvdXBfaW5mbywgdmFyKSB7CiAgIyBSdW4gVHVrZXkncyB0ZXN0IGZvciB0aGUgZ2l2ZW4gdmFyaWFibGUKICB0dWtleV9yZXMgPC0gdHVrZXlfaHNkKGRmLCBhcy5mb3JtdWxhKHBhc3RlKHZhciwgIn4gdHJlYXRlbWVudCIpKSkKICAKICAjIENyZWF0ZSBhIG1hdHJpeCBvZiBwLXZhbHVlcyBiZXR3ZWVuIHRyZWF0bWVudCBncm91cHMKICBncm91cHMgPC0gc29ydCh1bmlxdWUoZGYkdHJlYXRlbWVudCkpCiAgcG1hdCA8LSBtYXRyaXgoMSwgbnJvdyA9IGxlbmd0aChncm91cHMpLCBuY29sID0gbGVuZ3RoKGdyb3VwcyksCiAgICAgICAgICAgICAgICAgZGltbmFtZXMgPSBsaXN0KGdyb3VwcywgZ3JvdXBzKSkKICAKICBpZihucm93KHR1a2V5X3JlcykgPiAwKSB7CiAgICBmb3IoaSBpbiBzZXFfbGVuKG5yb3codHVrZXlfcmVzKSkpIHsKICAgICAgZ3JwMSA8LSB0dWtleV9yZXMkZ3JvdXAxW2ldCiAgICAgIGdycDIgPC0gdHVrZXlfcmVzJGdyb3VwMltpXQogICAgICBwX3ZhbCA8LSB0dWtleV9yZXMkcC5hZGpbaV0KICAgICAgcG1hdFtncnAxLCBncnAyXSA8LSBwX3ZhbAogICAgICBwbWF0W2dycDIsIGdycDFdIDwtIHBfdmFsCiAgICB9CiAgfQogIAogICMgQ29tcHV0ZSBncm91cGluZyBsZXR0ZXJzCiAgbGV0dGVyc19vdXQgPC0gbXVsdGNvbXBMZXR0ZXJzKHBtYXQsIHRocmVzaG9sZCA9IDAuMDUpJExldHRlcnMKICAKICAjIFJldHVybiBvbmx5IHRoZSB0cmVhdG1lbnQgYW5kIGxldHRlciBjb2x1bW5zLgogICMgVGhlIGdyb3VwaW5nIHZhcmlhYmxlICh0cmVhdF9kYXkpIGlzIGFkZGVkIGF1dG9tYXRpY2FsbHkuCiAgZGF0YS5mcmFtZSh0cmVhdGVtZW50ID0gbmFtZXMobGV0dGVyc19vdXQpLCAKICAgICAgICAgICAgIGxldHRlciA9IGxldHRlcnNfb3V0LCAKICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKfQoKCgpsZXR0ZXJzX2xpc3QgPC0gbGFwcGx5KHN0YXRpc3RpY3MsIGZ1bmN0aW9uKHZhcikgewogIGZpbHRfZW9kX21lYXN1cmVtZW50X2RhdGEgJT4lCiAgICBncm91cF9ieSh0cmVhdF9kYXkpICU+JQogICAgZ3JvdXBfbW9kaWZ5KH4gZ2V0X2xldHRlcnNfYnlfZGF5KC54LCAueSwgdmFyKSkgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBtdXRhdGUodmFyaWFibGUgPSB2YXIpCn0pCmFsbF9sZXR0ZXJzIDwtIGJpbmRfcm93cyhsZXR0ZXJzX2xpc3QpCgoKCiMgTm93LCBjcmVhdGUgeW91ciBzdW1tYXJ5IHRhYmxlIGFzIGJlZm9yZS4KIyAoV2UgYXNzdW1lIHRoZSBzdW1tYXJ5X3RhYmxlIHdhcyBjb21wdXRlZCBhcyBpbiB5b3VyIHByZXZpb3VzIGNodW5rLikKc3VtbWFyeV90YWJsZSA8LSBmaWx0X2VvZF9tZWFzdXJlbWVudF9kYXRhICU+JQogIGdyb3VwX2J5KHRyZWF0X2RheSwgdHJlYXRlbWVudCkgJT4lICAjIEdyb3VwIGJ5IGRheSBhbmQgdHJlYXRtZW50CiAgc3VtbWFyaXNlKGFjcm9zcyhhbGxfb2Yoc3RhdGlzdGljcyksCiAgICAgICAgICAgICAgICAgICB+IHNwcmludGYoIiUuMmYgwrEgJS4yZiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oLngsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkKC54LCBuYS5ybSA9IFRSVUUpKSksCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICAjIENvbWJpbmUgbWVhbiBhbmQgc2QgaW50byBhIHNpbmdsZSBjb2x1bW4KCiMgRm9yIG5pY2VyIGNvbHVtbiBuYW1lcywgcmVuYW1lICh5b3UgY2FuIGFkanVzdCB0aGlzIG1hcHBpbmcgYXMgbmVlZGVkKS4KY29sbmFtZXMoc3VtbWFyeV90YWJsZSkgPC0gYygiVHJlYXRtZW50IERheSIsIlRyZWF0bWVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkR1cmF0aW9uIiwiUDEgRHVyYXRpb24iLCJQMiBEdXJhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZQMi92UDEiLCJ0UDIiLCLPhCIsImFQMCIsInZQMCIsInNTMSIsInZQMSIsInZQMiIpCgojIFNpbmNlIG91ciBsZXR0ZXJzIGFyZSBrZXllZCBieSB0aGUgb3JpZ2luYWwgdmFyaWFibGUgbmFtZXMgKGUuZy4sICJkdXJhdGlvbiIpIAojIHdlIHNldCB1cCBhIG1hcHBpbmcgdG8gbWF0Y2ggdGhlIHN1bW1hcnlfdGFibGUgY29sdW1ucy4KbWFwcGluZ19kZiA8LSB0aWJibGUoCiAgVmFyaWFibGUgPSBjKCJEdXJhdGlvbiIsICJQMSBEdXJhdGlvbiIsICJQMiBEdXJhdGlvbiIsICJ2UDIvdlAxIiwgCiAgICAgICAgICAgICAgICJ0UDIiLCAiz4QiLCAiYVAwIiwgInZQMCIsICJzUzEiLCAidlAxIiwgInZQMiIpLAogIHZhciA9IHN0YXRpc3RpY3MKKQoKIyBSZXNoYXBlIHRoZSBzdW1tYXJ5X3RhYmxlIHRvIGxvbmcgZm9ybWF0IHRvIG1lcmdlIHRoZSBsZXR0ZXJzLgpzdW1tYXJ5X2xvbmcgPC0gc3VtbWFyeV90YWJsZSAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1jKGBUcmVhdG1lbnQgRGF5YCwgVHJlYXRtZW50KSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiVmFyaWFibGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiU3VtbWFyeSIpICU+JQogIGxlZnRfam9pbihtYXBwaW5nX2RmLCBieSA9ICJWYXJpYWJsZSIpCgojIE1lcmdlIHdpdGggdGhlIGxldHRlcnMgKGpvaW4gYnkgdHJlYXRfZGF5L1RyZWF0bWVudCBhbmQgdGhlIHZhcmlhYmxlIGtleSkuCiMgTm90ZTogSW4gc3VtbWFyeV90YWJsZSwgIlRyZWF0bWVudCBEYXkiIGNvcnJlc3BvbmRzIHRvICJ0cmVhdF9kYXkiIGluIGFsbF9sZXR0ZXJzLgpzdW1tYXJ5X2xvbmcgPC0gc3VtbWFyeV9sb25nICU+JQogIGxlZnRfam9pbihhbGxfbGV0dGVycywgYnkgPSBjKCJ2YXIiID0gInZhcmlhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJlYXRtZW50IERheSIgPSAidHJlYXRfZGF5IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJlYXRtZW50IiA9ICJ0cmVhdGVtZW50IikpCgojIEFwcGVuZCB0aGUgc2lnbmlmaWNhbmNlIGxldHRlciAoaWYgYXZhaWxhYmxlKSB0byB0aGUgc3VtbWFyeSBzdHJpbmcuCnN1bW1hcnlfbG9uZyA8LSBzdW1tYXJ5X2xvbmcgJT4lCiAgbXV0YXRlKFN1bW1hcnkgPSBpZmVsc2UoaXMubmEobGV0dGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBTdW1tYXJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlMChTdW1tYXJ5LCAiICgiLCBsZXR0ZXIsICIpIikpKQoKIyAoT3B0aW9uYWwpIFBpdm90IGJhY2sgdG8gd2lkZSBmb3JtYXQuCnN1bW1hcnlfd2lkZSA8LSBzdW1tYXJ5X2xvbmcgJT4lCiAgc2VsZWN0KC12YXIsIC1sZXR0ZXIpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBWYXJpYWJsZSwgdmFsdWVzX2Zyb20gPSBTdW1tYXJ5KQoKIyBDcmVhdGUgYSBmbGV4dGFibGUgZnJvbSB0aGUgdXBkYXRlZCBzdW1tYXJ5X3dpZGUgdGFibGUuCmZsZXh0YWJsZV90YWJsZV9zaWcgPC0gZmxleHRhYmxlKHN1bW1hcnlfd2lkZSkgJT4lCiAgYmcocGFydCA9ICJoZWFkZXIiLCBiZyA9ICIjRDNEM0QzIikgJT4lICAjIEhlYWRlciBiYWNrZ3JvdW5kIGNvbG9yCiAgYm9sZChwYXJ0ID0gImhlYWRlciIpICU+JSAgICAgICAgICAgICAgICMgQm9sZCBoZWFkZXIgcm93CiAgZm9udHNpemUoc2l6ZSA9IDEwLCBwYXJ0ID0gImFsbCIpICU+JSAgICMgRm9udCBzaXplIGZvciBlbnRpcmUgdGFibGUKICBhdXRvZml0KCkgJT4lICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBBZGp1c3QgY29sdW1uIHdpZHRocwogIHNldF90YWJsZV9wcm9wZXJ0aWVzKGxheW91dCA9ICJhdXRvZml0IikgJT4lICAgICAgIyBGaXQgdGFibGUgdG8gbGF5b3V0CiAgbGluZV9zcGFjaW5nKGkgPSBOVUxMLCBzcGFjZSA9IDEuMikgICAgICAgIyBCZXR0ZXIgcmVhZGFiaWxpdHkKCiMgRGVmaW5lIGxhbmRzY2FwZSBzZWN0aW9uIHByb3BlcnRpZXMgZm9yIFdvcmQgZXhwb3J0CmxhbmRzY2FwZV9zZWN0aW9uIDwtIGJsb2NrX3NlY3Rpb24oCiAgcHJvcF9zZWN0aW9uKAogICAgcGFnZV9zaXplID0gcGFnZV9zaXplKG9yaWVudCA9ICJsYW5kc2NhcGUiKSAjIExhbmRzY2FwZSBvcmllbnRhdGlvbgogICkKKQoKIyBDcmVhdGUgdGhlIFdvcmQgZG9jdW1lbnQgd2l0aCB0aGUgdXBkYXRlZCBmbGV4dGFibGUuCmRvYyA8LSByZWFkX2RvY3goKSAlPiUKICBib2R5X2FkZF9mbGV4dGFibGUoZmxleHRhYmxlX3RhYmxlX3NpZykgJT4lICAjIEFkZCBmbGV4dGFibGUKICBib2R5X2FkZChsYW5kc2NhcGVfc2VjdGlvbikgICAgICAgICAgICAgICAgICAjIEFwcGx5IGxhbmRzY2FwZSBsYXlvdXQKCiMgRXhwb3J0IHRoZSBXb3JkIGRvY3VtZW50LgpwcmludChkb2MsIHRhcmdldCA9IGZpbGUucGF0aChyb290LCJvdXRwdXRfZGF0YS9lb2Rfc3VtbWFyeV9ub3JtX3dpdGhfc2lnLmRvY3giKSkKCiMgRGlzcGxheSB0aGUgdXBkYXRlZCBmbGV4dGFibGUgaW4gdGhlIFIgTWFya2Rvd24gb3V0cHV0LgpmbGV4dGFibGVfdGFibGVfc2lnCmBgYA==